//
//  main.m
//  第一个OC类- 方法
//
//  Created by wenjim on 17/8/24.
//  Copyright © 2017年 WenJim. All rights reserved.
//

#import <Foundation/Foundation.h>

/*
 事物名称：iPhone
 属性  ： 颜色，型号，cpu，尺寸   ＝＝＝ 成员变量
 行为  ：打电话，发短信，上网     ＝＝＝ 成员方法
 
 C语言中函数分为声明和实现
 OC中定义一个类也分为声明和实现，以后在OC中定义类，就是写类的声明和实现
 */


// 类名后面的 :NSObject 是为了让我们的IPhone 类具备创建对象的能力
// 1. 编写类的声明
@interface IPhone : NSObject
{
    // 注意：默认情况下，OC对象中的属性是不能直接访问的
@public // 只要让类中的属性公开，以后就可以直接通过一个指向结构体的指针来操作对象中的属性
    float _model; // 型号
    int _cpu; // cpu
    double _size; // 尺寸
    int _color; // 颜色
}

// 行为
// OC中的行为和C语言中的函数一样，都是用来保存一段特定功能的代码
// C语言中定义一个函数，分为声明和实现,声明卸载.h中，实现写在.c中
// OC中定义一个方法，也分声明和实现，声明写在@interface中，实现写在@implementation

// C语言的函数分为两种：内部函数和外部函数
// OC中的方法也分为两种：类方法和对象方法
// 类方法只能用类名调用，对象方法只能用对象调用
// OC中的类方法用+表示，OC中的对象方法用-表示

// 编写C语言函数的规律：1.确定函数名称 2.确定形参 3.确定返回值 4.确定返回值类型
// 编写OC方法也有规律，规律和C语言一模一样

/*  // C语言
void about()
{
    printf("model = %i, Cpu  = %i, size = color");
}
*/


/*
 C语言的函数：
 没有返回值没有参数的
 没有返回值有参数的
 有返回值没有参数的
 有返回值有参数的
 
 OC的方法也是一样的：
 没有返回值没有参数的
 没有返回值有参数的
 有返回值没有参数的
 有返回值有参数的
 */

// 注意：OC的方法，如果没有形参不需要写()，而是直接写一个;
// 为什么OC中没有形参不需要写()呢？因为OC方法中的()有特殊用途，OC方法中的()用来括住数据类型的
// 没有返回值没有参数
-(void)about;



// 有返回值没有参数的，读取短信
-(char *)loadMessage;

// 有返回值有参数，打电话
// C语言 中的写法
// int call(int number)

// OC 的写法  注意：OC中的方法如果有参数，那么每个参数的数据类型前面必须加上一个:
// 注意：当前这个有参数的方法，它的方法名称是  signal:
//      冒号也是方法名称的一部分
- (int)call:(int)number;
// 有返回值并且有多个参数，发短信
// C语言
// int sendMessage(int number,char * content);
// OC
// 下面这个方法的名称是 sendMessage::
- (int)sendMessage:(int)number :(char *)content;

// 为了提高我们的阅读性，OC方法允许我们给每个参数添加一个标签来说明当前参数的含义
// 注意：标签也是方法名的一部分
// 方法名是 sendMessageWithNumber:content:
- (int)sendMessageWithNumber:(int)number content:(char *)content;

@end

// 2.编写类的实现
// 以@implementation开头，以@end结尾，然后在class对应的地方写上声明的类的名称，必须和声明的类名一模一样
@implementation IPhone

// 行为的实现
-(void)about
{
    // 如果在对象方法中像访问该对象的属性，可以直接写上 _属性名称 即可
    
//    NSLog(@"打印本机信息\n");
    NSLog(@"尺寸 = %f, cpu = %i, 型号 = %.f, 颜色 = %i\n",_size,_cpu,_model,_color);
}

// 读短信
-(char *)loadMessage
{
    return "今天吃什么？";
}

// 打电话
- (int)call:(int)number
{
    
    NSLog(@"拨打%i",number);
    
    return 2;
}

// 发短信
- (int)sendMessage:(int)number :(char *)content
{
    NSLog(@"发送短信给%i,内容是%s",number,content);
    return 1;
}

- (int)sendMessageWithNumber:(int)number content:(char *)content
{
    NSLog(@"发送短信给%i,内容是%s",number,content);
    return 1;
}

@end

int main(int argc, const char * argv[]) {
    
    // 如何通过一个类来创建对象
    // 在OC中想要通过一个类来创建一个对象，必须给类发送一个消息（好比C语言中调用方法一样）
    // 如何发送消息？ 在OC中只要想要发送消息就先写上 [类名称／对象对象 方法名称];
    // 发送什么消息（调用什么方法） 可以创建一个对象呢？new
    
    /*
     只要通过一个类调用类的new方法，给类发送一个叫做new的消息之后，系统内部会做3件事情
     1. 为了IPhone类创建出来的对象分配存储空间
     2. 初始化IPhone类创建出来的对象中的属性
     3. 返回IPhone类创建出来的对象对应的地址
     */
    
    // 通过一个IPhone类型的指针接受了 IPhone对象的地址
    // 如果使用给一个指针保存了某一对象的地址，那我们称这个指针为某个类型的对象
    // 利用IPhone类型的指针保存了IPhone对象的地址，那我们就称IPhone类型的指针p为IPhone对象
    
    // 通过类创建对象
    IPhone * p = [IPhone new];
    // 修改对象的属性
    p->_size = 3.5;
    p->_cpu = 2;
    p->_model = 5;
    p->_color =0;
    
//    NSLog(@"size = %f, cpu = %i, model = %f, color = %i\n",p->_size,p->_cpu,p->_model,p->_color);
    

    // 如果给对象发消息(如果调用对象的方法)
    // [类名／对象 消息名称（方法名称）]
    [p about];
    
    // [对象 消息名称（方法名称）]
    // 注意：OC中的NSLog对C语言的字符串支持不是很好，如果返回的是中文的C语言字符串可能输出的是乱码，也可能什么都不输出
    char * message = [p loadMessage];
    
    NSLog(@"短信为：%s\n",message);
    
    // 打电话
    [p call:130052500];
    
    // 发短信
    [p sendMessage:1300525003 :"NO.1"];
    
    [p sendMessageWithNumber:1300525003 content:"NO.2"];
    
    return 0;
}
